home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Dots & Pixels / sources / vretrace.cp < prev    next >
Text File  |  1995-09-29  |  4KB  |  150 lines

  1. #include <Retrace.h>
  2. #include <Devices.h>
  3. #include <SegLoad.h>
  4. #include <Timer.h>
  5.  
  6. #include "stopwatch.h"
  7. #include "vretrace.h"
  8.  
  9. // #define _DEBUG_
  10.  
  11. VBLUPP vretrace::theVBLProcPtr = allocateVBL();
  12.  
  13. VBLUPP vretrace::allocateVBL( void)
  14. {
  15.     //
  16.     // Determine size of theVBLProc
  17.     //
  18.     Handle VBL_resource = Get1Resource( 'VBL ', 128);
  19.     
  20.     if( VBL_resource == 0)
  21.     {
  22.         DebugStr( "\pcould not get VBL resource. Exit immediately!");
  23.     }
  24.     theVBLProcPtr = (VBLUPP)NewRoutineDescriptor(
  25.             (ProcPtr)(*VBL_resource), uppVBLProcInfo, kM68kISA | kOld68kRTA);
  26.     
  27.     return theVBLProcPtr;
  28. }
  29.  
  30. int vretrace::start()
  31. {
  32.     int result = -1;
  33.     if( !is_running)
  34.     {
  35.         result = (int)SlotVInstall( (QElem *)&myVBLTask, mySlot);
  36.         if( result == noErr)
  37.         {
  38.             is_running = true;
  39.         }
  40.     }
  41.     #ifdef _DEBUG_
  42.         cout << "vretrace::start() returns " << result << "\n";
  43.     #endif
  44.     return result;
  45. }
  46.  
  47. int vretrace::stop()
  48. {
  49.     int result = -1;
  50.     if( is_running)
  51.     {
  52.         result = (int)SlotVRemove( (QElem *)&myVBLTask, mySlot);
  53.         if( result == noErr)
  54.         {
  55.             is_running = false;
  56.         }
  57.     }
  58.     #ifdef _DEBUG_
  59.         cout << "vretrace::stop() returns " << result << "\n";
  60.     #endif
  61.     return result;
  62. }
  63.  
  64. void vretrace::init( const short theSlot, const short how_often)
  65. {
  66.     myVBLTask.qType    = vType;
  67.     myVBLTask.vblAddr  = theVBLProcPtr;
  68.     myVBLTask.vblCount = how_often;
  69.     //
  70.     // 940211:
  71.     // From IM, Phonebook edition, page 4 from the Vertical Retrace Manager chapter:
  72.     //
  73.     // VBLPhase contains an integer (smaller than vblCount) used…
  74.     //
  75.     // Possibly the _deep_ problem with 'framerate_of_main_monitor' is
  76.     // caused by the fact that I changed
  77.     //
  78.     //                    myVBLTask.vblPhase = how_often % 9;
  79.     // to
  80.     //                    myVBLTask.vblPhase = (short)this % 9;    // just something
  81.     // some time ago.
  82.     //
  83.     myVBLTask.vblPhase = (short)this % how_often;    // just something
  84.     the_interval = how_often;
  85.     numtimes_run = 0L;
  86.     is_running   = false;
  87.     mySlot       = theSlot;
  88. }
  89.  
  90. unsigned long vretrace::reset( const unsigned long new_value)
  91. {
  92.     const unsigned long result = numtimes_run;
  93.     numtimes_run = new_value;
  94.     return result;
  95. }
  96.  
  97. unsigned long vretrace::sync( const unsigned long count)
  98. {
  99.     const unsigned long goal = numtimes_run + count;
  100.     sync_till( goal);
  101.     return goal;
  102. }
  103.  
  104. void vretrace::sync_till( const unsigned long goal)
  105. {
  106.     //
  107.     // Note: we do not do
  108.     //
  109.     //         while( (numtimes_run != goal)){};
  110.     //
  111.     // since we just might possible miss a tick (I can't see how, but one
  112.     // never knows (e.g. on a PowerBook going to sleep or something like that)
  113.     //
  114.     if( numtimes_run > goal)
  115.     {
  116.         //
  117.         // going to pass through zero (this doesn't happen very often ;-),
  118.         // but we do check for it, anyway. 940823: we suddenly enter this loop
  119.         // when we don't want to enter it. This is caused by the passing of
  120.         // a negative number to 'sync' (FormExp issues a 2 second early warning
  121.         // even if interstimulus time is less than 2 seconds. This results in a
  122.         // negative amount of time between the end of an experiment and the
  123.         // subsequent early warning) => This looks cool, again.
  124.         //
  125.         while( numtimes_run > goal){};
  126.     }
  127.     while( numtimes_run < goal){};
  128. }
  129.  
  130. short vretrace::getslot( const GDHandle gDev)
  131. {
  132.     const short refNum =(**gDev).gdRefNum;   // video driver refNum for this GDevice
  133.     return (**(AuxDCEHandle)GetDCtlEntry( refNum)).dCtlSlot; // slot in which this video card sits
  134. }    
  135.  
  136. double monitor_framerate( GDHandle the_gDevice)
  137. {
  138.     stopwatch omega;
  139.     vretrace flicker( the_gDevice);
  140.     
  141.     flicker.start();
  142.     
  143.     flicker.sync();
  144.     omega.start();
  145.     flicker.sync( 10);
  146.     const double num_micros = omega.microseconds( omega.stop());
  147.  
  148.     return (10000000.0 / num_micros);
  149. }
  150.